﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using SMG.Domain.Repository.Migration;
using SMG.Application.DTO.Migration;
using SMG.Application.Extension;
using SMG.ServiceContract.Migration;
using Infrastructure.Core.Common;
using SMG.Domain.Model.Migration;
using SMG.Domain.Repository;
using SMG.Domain.Specifications;
using SMG.Domain.Specifications.Migration;

namespace SMG.Application.Migration
{
    public class PlayMoveServiceImpl : ApplicationService, IPlayMoveService
    {
        private IPlayRecordRepository playRecordRepository;
        private IFirstTaskRepository firstTaskRepository;
        private IFirstTaskDetailRepository firstTaskDetailRepository;
        private IFirstTaskStateRepository firstTaskStateRepository;
        private IFirstTaskDetailStateRepository firstTaskDetailStateRepository;
        private ISecondTaskRepository secondTaskRepository;
        private ISecondTaskDetailRepository secondTaskDetailRepository;

        public PlayMoveServiceImpl(IRepositoryContext context,
                                    IPlayRecordRepository playRecordRepository,
                                    IFirstTaskRepository firstTaskRepository,
                                    IFirstTaskDetailRepository firstTaskDetailRepository,
                                    IFirstTaskStateRepository firstTaskStateRepository,
                                    IFirstTaskDetailStateRepository firstTaskDetailStateRepository,
                                    ISecondTaskRepository secondTaskRepository,
                                    ISecondTaskDetailRepository secondTaskDetailRepository)
            : base(context)
        {
            this.playRecordRepository = playRecordRepository;
            this.firstTaskRepository = firstTaskRepository;
            this.firstTaskDetailRepository = firstTaskDetailRepository;
            this.firstTaskStateRepository = firstTaskStateRepository;
            this.firstTaskDetailStateRepository = firstTaskDetailStateRepository;
            this.secondTaskRepository = secondTaskRepository;
            this.secondTaskDetailRepository = secondTaskDetailRepository;

            this.playRecordRepository.SetContext(context);
            this.firstTaskRepository.SetContext(context);
            this.firstTaskDetailRepository.SetContext(context);
            this.firstTaskStateRepository.SetContext(context);
            this.firstTaskDetailStateRepository.SetContext(context);
            this.secondTaskRepository.SetContext(context);
            this.secondTaskDetailRepository.SetContext(context);
        }

        #region 一级任务

        /// <summary>
        /// 获取未处理的一级迁移任务
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public IEnumerable<PlayRecordDto> GetFirstMoveTask(int count)
        {
            var specification = new AndSpecification<PlayRecord>(new PlayMoveStatusEqualSpecification(0), new PlayTaskStatusEqualSpecification(0));
            //specification = new AndSpecification<PlayRecord>(specification, new PlayTypeEqualSpecification(0));
            specification = new AndSpecification<PlayRecord>(specification, new PlayLockStatusEqualSpecification(0));
            var query = playRecordRepository.QueryBy(specification);
            var records = query.Take(count).ToList();
            if (records == null || !records.Any()) return null;
            //先锁定这些记录
            records.ForEach(p =>
            {
                p.LockStatus = 1;
                playRecordRepository.Update(p);
                Context.Commit();
            });
            return records.ConvertToPlayRecordDto();
        }
        /// <summary>
        /// 添加一级迁移任务
        /// </summary>
        /// <param name="taskDto"></param>
        /// <param name="taskDetailDtos"></param>
        /// <returns></returns>
        public bool AddFirstMoveTask(FirstMoveTaskDto taskDto, IEnumerable<FirstMoveTaskDetailDto> taskDetailDtos)
        {
            var result = false;
            try
            {

                var task = taskDto.ConvertToDomain();
                firstTaskRepository.Create(task);
                result = Context.Commit();
                if (result)
                {
                    var taskDetails = taskDetailDtos.ToList().ConvertToDomain();
                    foreach (var detail in taskDetails)
                    {
                        detail.MainTaskID = task.ID;
                        firstTaskDetailRepository.Create(detail);
                    }
                    result = Context.Commit();
                    taskDetailDtos = taskDetails.ConvertToDto();
                }
            }
            catch (Exception ex)
            {

            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tasks"></param>
        /// <returns></returns>
        public Boolean AddFirstMoveTask(IDictionary<FirstMoveTaskDto, IEnumerable<FirstMoveTaskDetailDto>> taskDict) {

            if (taskDict == null) return false;

            var result = false;
            try
            {
                foreach (var taskItem in taskDict)
                {
                    var task = taskItem.Key.ConvertToDomain();
                    firstTaskRepository.Create(task);
                    result = Context.Commit();
                    if (result)
                    {
                        var taskDetails = taskItem.Value.ToList().ConvertToDomain();
                        foreach (var detail in taskDetails)
                        {
                            detail.MainTaskID = task.ID;
                            firstTaskDetailRepository.Create(detail);
                        }
                        result = Context.Commit();
                    }
                    else
                        throw new Exception("保存一级任务失败");
                }
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 根据节目图表id查询任务详细列表
        /// </summary>
        /// <param name="playId"></param>
        /// <returns></returns>
        public IEnumerable<FirstMoveTaskDetailDto> QueryFirstTaskDetails(long playId)
        {
            var query = firstTaskDetailRepository.QueryBy(new FirstTaskDetailPlayIDEqualSpecification(playId));
            return query.ToList().ConvertToDto();
        }
        /// <summary>
        /// 获取主任务状态列表
        /// </summary>
        /// <param name="playId"></param>
        /// <returns></returns>
        public IEnumerable<FirstMoveTaskStateDto> QueryFirstTaskState(long playId) {
            var query = firstTaskStateRepository.QueryBy(new FirstTaskStatePlayIDEqualSpecification(playId));
            return query.ToList().ConvertToDto();
        }
        /// <summary>
        /// 获取一级迁移明细状态数据
        /// </summary>
        /// <param name="playId"></param>
        /// <returns></returns>
        public IEnumerable<FirstMoveTaskDetailStateDto> QueryFirstTaskDetailState(long playId)
        {
            var query = firstTaskDetailStateRepository.QueryBy(new FirstTaskDetailStatePlayIDEqualSpecification(playId));
            return query.ToList().ConvertToDto();
        }

        #endregion

        #region 二级任务

        /// <summary>
        /// 获取未处理的二级迁移任务
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public IEnumerable<PlayRecordDto> GetSecondMoveTask(int count)
        {
            var specification = new AndSpecification<PlayRecord>(new PlayMoveStatusEqualSpecification(1), new PlayTaskStatusEqualSpecification(1));
            //specification = new AndSpecification<PlayRecord>(specification, new PlayTypeEqualSpecification(0));
            specification = new AndSpecification<PlayRecord>(specification, new PlayLockStatusEqualSpecification(0));
            var query = playRecordRepository.QueryBy(specification);
            var records = query.Take(count).ToList();
            if (records == null || !records.Any()) return null;
            //先锁定这些记录
            records.ForEach(p =>
            {
                p.LockStatus = 1;
                playRecordRepository.Update(p);
                Context.Commit();
            });
            return records.ConvertToPlayRecordDto();
        }
        /// <summary>
        /// 添加二级迁移任务
        /// </summary>
        /// <param name="taskDto"></param>
        /// <param name="taskDetailDtos"></param>
        /// <returns></returns>
        public bool AddSecondMoveTask(SecondMoveTaskDto taskDto, IEnumerable<SecondMoveTaskDetailDto> taskDetailDtos)
        {
            var result = false;
            try
            {
                var task = taskDto.ConvertToDomain();
                secondTaskRepository.Create(task);
                result = Context.Commit();
                if (result)
                {
                    var taskDetails = taskDetailDtos.ToList().ConvertToDomain();
                    foreach (var detail in taskDetails)
                    {
                        detail.MainTaskID = task.ID;
                        secondTaskDetailRepository.Create(detail);
                    }
                    result = Context.Commit();
                    taskDetailDtos = taskDetails.ConvertToDto();
                }
            }
            catch (Exception ex)
            {

            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tasks"></param>
        /// <returns></returns>
        public Boolean AddSecondMoveTask(IDictionary<SecondMoveTaskDto, IEnumerable<SecondMoveTaskDetailDto>> taskDict)
        {
            if (taskDict == null) return false;

            var result = false;
            try
            {
                foreach (var taskItem in taskDict)
                {
                    var task = taskItem.Key.ConvertToDomain();
                    secondTaskRepository.Create(task);
                    result = Context.Commit();
                    if (result)
                    {
                        var taskDetails = taskItem.Value.ToList().ConvertToDomain();
                        foreach (var detail in taskDetails)
                        {
                            detail.MainTaskID = task.ID;
                            secondTaskDetailRepository.Create(detail);
                        }
                        result = Context.Commit();
                    }
                    else
                        throw new Exception("保存二级任务失败");
                }
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 设置节目单二级任务状态
        /// </summary>
        /// <param name="playRecords"></param>
        /// <returns></returns>
        public bool SetPlaySecondMoveTask(PlayRecordDto playRecord)
        {
            if (playRecord == null)
                return false;

            playRecord.TaskStatus = 2;
            playRecord.LockStatus = 0;
            playRecordRepository.Update(playRecord.ConvertToPlayRecord());

            return Context.Commit();
        }
        /// <summary>
        /// 设置节目单二级任务状态
        /// </summary>
        /// <param name="playRecords"></param>
        /// <returns></returns>
        public bool SetPlaySecondMoveTask(IEnumerable<PlayRecordDto> playRecords)
        {
            var result = false;

            foreach (var play in playRecords)
            {
                play.LockStatus = 0;
                playRecordRepository.Update(play.ConvertToPlayRecord());
            }

            result = Context.Commit();
            return result;
        }

        #endregion

        /// <summary>
        /// UnLockPlayRecord
        /// </summary>
        /// <param name="playRecords"></param>
        /// <returns></returns>
        public bool UnLockPlayRecord(PlayRecordDto playRecord)
        {
            if (playRecord == null)
                return false;

            playRecord.LockStatus = 0;
            playRecordRepository.Update(playRecord.ConvertToPlayRecord());

            return Context.Commit();
        }

        #region 上传xml

        /// <summary>
        /// 获取待上传的节目单列表
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public IEnumerable<PlayRecordDto> GetWaitUploadXmlPlay(int count)
        {
            var specification = new AndSpecification<PlayRecord>(new PlayMoveStatusEqualSpecification(2), new PlayTaskStatusEqualSpecification(2));
            specification = new AndSpecification<PlayRecord>(specification, new PlayTypeEqualSpecification(0));
            specification = new AndSpecification<PlayRecord>(specification, new PlayLockStatusEqualSpecification(0));
            specification = new AndSpecification<PlayRecord>(specification, new PlayCGFlagEqualSpecification (0));
            var query = playRecordRepository.QueryBy(specification);
            var records = query.Take(count).ToList();
            if (records == null || !records.Any()) return null;
            //先锁定这些记录
            records.ForEach(p =>
            {
                p.LockStatus = 1;
                playRecordRepository.Update(p);
                Context.Commit();
            });
            return records.ConvertToPlayRecordDto();
        }

        /// <summary>
        /// 设置上传节目单xml状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool SetWaitUploadXmlPlay(PlayRecordDto dto)
        {
            if (dto == null)
                return false;

            playRecordRepository.Update(dto.ConvertToPlayRecord());

            return Context.Commit();
        }

        #endregion

    }
}
